package com.jack.netty.udp.server;

import com.jack.netty.log.DefaultLogger;
import com.jack.netty.log.LoggerManager;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;


/**
 * Created by jack on 15/12/11.
 * netty UDP 单播,全网广播消息接收器
 */
public class UdpServer {

    private Bootstrap bootstrap;
    private EventLoopGroup eventLoopGroup;
    private int port = 9999;    //监听端口
    private boolean restartFlag = true; //如果启动异常或者异常关闭是否自动重启
    private UdpServerListener udpServerListener = null; //设置udp消息处理监听器

    private UdpServerHandler udpServerHandler;  //内部处理器

    public UdpServer(){

    }


    public void start(){
        LoggerManager.getInstance().getiLogger().info(getClass(),"即将启动UDP单播广播服务");
        bootstrap = new Bootstrap();
        eventLoopGroup = new NioEventLoopGroup();
        bootstrap.group(eventLoopGroup);
        bootstrap.channel(NioDatagramChannel.class);
        bootstrap.option(ChannelOption.SO_BROADCAST,true);
        udpServerHandler = new UdpServerHandler();
        udpServerHandler.setUdpServerListener(udpServerListener);
        bootstrap.handler(udpServerHandler);
        try {
            ChannelFuture channelFuture = bootstrap.bind(port).sync();
            channelFuture.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if(future.isSuccess()){
                        LoggerManager.getInstance().getiLogger().info(getClass(),"启动UDP单播广播服务成功,端口:"+port);
                    }else{
                        if(restartFlag){
                            restart();
                        }
                    }
                }
            });
            channelFuture.channel().closeFuture().await();
        }catch (Exception e){
            LoggerManager.getInstance().getiLogger().error(getClass(),"启动UDP单播广播服务错误:"+e.getMessage());
        }finally {
            if(restartFlag){
                restart();
            }else{
                stop();
            }
        }

    }

    public void stop(){
        if(eventLoopGroup != null){
            eventLoopGroup.shutdownGracefully();
        }
    }

    public void restart(){
        stop();
        try {
            LoggerManager.getInstance().getiLogger().info(getClass(),"UDP单播广播服务器即将重启");
            Thread.sleep(1000);
        }catch (Exception e){
            LoggerManager.getInstance().getiLogger().error(getClass(),"重启睡眠错误:"+e == null ? "" : e.getMessage());
        }
        start();
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public UdpServerListener getUdpServerListener() {
        return udpServerListener;
    }

    public void setUdpServerListener(UdpServerListener udpServerListener) {
        this.udpServerListener = udpServerListener;
    }



    public static void main(String[] args){
        //设置日志
        LoggerManager.getInstance().setiLogger(new DefaultLogger());

        //初始化服务器
        final UdpServer udpServer = new UdpServer();

        //设置监听端口
        udpServer.setPort(2323);

        //设置自定义监听器
        udpServer.setUdpServerListener(new SampleUdpServerListener());

        //在单独的线程中启动
        new Thread(new Runnable() {
            @Override
            public void run() {
                udpServer.start();
            }
        }).start();
    }


}
